﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using Gmantis.Controls.Automation;

namespace Gmantis.Controls
{
    [TemplatePart(Name = "HeaderEditor", Type = typeof(ContentControl)), 
    TemplatePart(Name = "ChildrenPanel", Type = typeof(ItemsPresenter)), 
    TemplatePart(Name = "HeaderPanelContainer", Type = typeof(Grid)), TemplatePart(Name = "HeaderPanel", Type = typeof(Grid)), 
    TemplateVisualState(Name = "Expanded", GroupName = "ExpandedStatesStates"), 
    TemplateVisualState(Name = "Collapsed", GroupName = "ExpandedStatesStates"), 
    TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"), 
    TemplatePart(Name = "Header", Type = typeof(ContentControl)), TemplatePart(Name = "ExpandButton", Type = typeof(ToggleButton))]
    public class TreeViewItem : HierarchicalPresenter
    {
        // Fields
        internal ItemsPresenter _elementChildrenPanel;
        internal ToggleButton _elementExpandButton;
        internal ContentControl _elementHeader;
        internal ContentControl _elementHeaderEditor;
        internal Grid _elementHeaderPanel;
        internal Grid _elementHeaderPanelContainer;
        private bool _ensureVisible;
        private bool _isEditing;
        internal bool _isLoaded;
        private AutomationPeer _peer;
        private TapHelper _tapHelper;
        internal bool _templateLoadedProperly;
        internal const string ChildrenPanelElementName = "ChildrenPanel";
        public static readonly DependencyProperty EditTemplateProperty = DependencyProperty.Register("EditTemplate", typeof(DataTemplate), typeof(TreeViewItem), null);
        internal const string ExpandButtonElementName = "ExpandButton";
        internal const string HeaderEditorElementName = "HeaderEditor";
        internal const string HeaderElementName = "Header";
        internal const string HeaderPanelContainerElementName = "HeaderPanelContainer";
        internal const string HeaderPanelElementName = "HeaderPanel";
        public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register("IsExpanded", typeof(bool), typeof(TreeViewItem), new PropertyMetadata(new PropertyChangedCallback(TreeViewItem.OnIsExpandedPropertyChanged)));
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(TreeViewItem), new PropertyMetadata(new PropertyChangedCallback(TreeViewItem.OnIsSelectedPropertyChanged)));
        public static readonly DependencyProperty LineDashArrayProperty = DependencyProperty.Register("LineDashArray", typeof(DoubleCollection), typeof(TreeViewItem), new PropertyMetadata(null));
        public static readonly DependencyProperty LineStrokeProperty = DependencyProperty.Register("LineStroke", typeof(Brush), typeof(TreeViewItem), new PropertyMetadata(new SolidColorBrush(Colors.Black)));
        public static readonly DependencyProperty LineThicknessProperty = DependencyProperty.Register("LineThickness", typeof(double), typeof(TreeViewItem), null);
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(TreeViewItem), null);
        internal static readonly DependencyProperty PositionProperty = DependencyProperty.Register("Position", typeof(ItemPosition), typeof(TreeViewItem), new PropertyMetadata(ItemPosition.Normal, new PropertyChangedCallback(TreeViewItem.IsLastItemChanged)));
        public static readonly DependencyProperty SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(TreeViewItem), null);
        internal static readonly DependencyProperty ShowLinesProperty = DependencyProperty.Register("ShowLines", typeof(bool), typeof(TreeViewItem), new PropertyMetadata(false, new PropertyChangedCallback(TreeViewItem.ShowLinesChanged)));
        public static readonly DependencyProperty TextAlignmentProperty = DependencyProperty.Register("TextAlignment", typeof(TextAlignment), typeof(TreeViewItem), null);
        public static readonly DependencyProperty TextDecorationsProperty = DependencyProperty.Register("TextDecorations", typeof(TextDecorationCollection), typeof(TreeViewItem), null);
        public static readonly DependencyProperty TextWrappingProperty = DependencyProperty.Register("TextWrapping", typeof(TextWrapping), typeof(TreeViewItem), null);

        // Events
        public event EventHandler<SourcedEventArgs> Click;
        public event EventHandler<SourcedEventArgs> Collapsed;
        public event EventHandler<SourcedEventArgs> Collapsing;
        public event EventHandler<SourcedEventArgs> Expanded;
        public event EventHandler<SourcedEventArgs> Expanding;

        // Methods
        public TreeViewItem()
        {
            RoutedEventHandler handler = null;
            base.DefaultStyleKey = typeof(TreeViewItem);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateExpandedStates(false);
                    this.ChangeVisualStateSelection(false);
                };
            }
            base.Loaded += handler;
            this.SetCustomDefaultValues();
        }

        private void ActivateEditor()
        {
            if (this._elementHeaderEditor != null)
            {
                Control control = this.GetChildrenOfType<Control>(this._elementHeaderEditor).FirstOrDefault<Control>();
                if (control != null)
                {
                    control.Focus();
                    TextBox box = this.GetChildrenOfType<TextBox>(this._elementHeaderEditor).FirstOrDefault<TextBox>();
                    if (box != null)
                    {
                        box.SelectAll();
                    }
                }
            }
        }

        private void TreeViewItem_LostFocus(object sender, RoutedEventArgs e)
        {
            FrameworkElement focusedElement = FocusManager.GetFocusedElement() as FrameworkElement;
            if (((this._elementHeaderEditor != null) && (focusedElement != null)) && !focusedElement.GetAllParents().Contains(this._elementHeaderEditor))
            {
                this.FinishEditing(false);
            }
        }

        protected void ChangeVisualStateExpandedStates(bool useTransitions)
        {
            if (!this.IsExpanded)
            {
                VisualStateHelper.GoToState(this, "Collapsed", useTransitions);
            }
            if (this.IsExpanded)
            {
                VisualStateHelper.GoToState(this, "Expanded", useTransitions);
            }
        }

        protected void ChangeVisualStateItemLine(bool useTransitions)
        {
            switch (this.Position)
            {
                case ItemPosition.Exclusive:
                    VisualStateHelper.GoToState(this, "ShowExclusiveItemLine", useTransitions);
                    return;

                case ItemPosition.Root:
                    VisualStateHelper.GoToState(this, "ShowRootItemLine", useTransitions);
                    return;

                case ItemPosition.Last:
                    VisualStateHelper.GoToState(this, "ShowLastItemLine", useTransitions);
                    return;
            }
            VisualStateHelper.GoToState(this, "ShowNormalItemLine", useTransitions);
        }

        protected void ChangeVisualStateSelection(bool useTransitions)
        {
            if (!this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Unselected", useTransitions);
            }
            if (this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Selected", useTransitions);
            }
        }

        protected void ChangeVisualStateShowLines(bool useTransitions)
        {
            if (this.ShowLines)
            {
                VisualStateHelper.GoToState(this, "ShowLines", useTransitions);
            }
            else
            {
                VisualStateHelper.GoToState(this, "HideLines", useTransitions);
            }
        }

        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            base.ClearContainerForItemOverride(element, item);
            this.TreeView.UnregisterDragSource(element as TreeViewItem);
            this.TreeView.ClearSelection(element);
        }

        public void Collapse()
        {
            this.IsExpanded = false;
        }

        public void EnsureVisible()
        {
            if (this._isLoaded)
            {
                this.ScrollIntoView(this.TreeView.ScrollViewer, this.Bounds);
                if (!this._elementHeader.Focus())
                {
                    base.Focus();
                }
            }
            else
            {
                this._ensureVisible = true;
            }
        }

        public void Expand()
        {
            this.IsExpanded = true;
        }

        internal void FinishEditing(bool cancel)
        {
            base.LostFocus -= new RoutedEventHandler(this.TreeViewItem_LostFocus);
            if ((this._elementHeaderEditor != null) && this._isEditing)
            {
                object header = base.Header;
                IEditableCollectionView itemsSource = base.ParentPresenter.ItemsSource as IEditableCollectionView;
                IEditableObject obj3 = header as IEditableObject;
                if (cancel)
                {
                    if (((itemsSource != null) && (itemsSource.CurrentEditItem == header)) && itemsSource.CanCancelEdit)
                    {
                        itemsSource.CancelEdit();
                    }
                    else if (obj3 != null)
                    {
                        obj3.CancelEdit();
                    }
                }
                else if ((itemsSource != null) && (itemsSource.CurrentEditItem == header))
                {
                    itemsSource.CommitEdit();
                }
                else if (obj3 != null)
                {
                    obj3.EndEdit();
                }
                this._elementHeader.Visibility = Visibility.Visible;
                this._elementHeaderEditor.Visibility = Visibility.Collapsed;
                this._isEditing = false;
            }
        }

        private IEnumerable<T> GetChildrenOfType<T>(DependencyObject e) where T : DependencyObject
        {
            if (e != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(e); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(e, i);
                    if ((child != null) && (child is T))
                    {
                        yield return (T)child;
                    }
                    IEnumerator<T> enumerator = this.GetChildrenOfType<T>(child).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        T current = enumerator.Current;
                        yield return current;
                    }
                }
            }
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TreeViewItem();
        }

        private DataTemplate GetItemDataTemplate(TreeViewItem tItem, object dataItem)
        {
            DataTemplate itemTemplate = null;
            if (base.ItemTemplateSelector != null)
            {
                itemTemplate = base.ItemTemplateSelector.SelectTemplate(dataItem, tItem);
            }
            if (base.ItemTemplate != null)
            {
                itemTemplate = base.ItemTemplate;
            }
            return itemTemplate;
        }

        private TreeViewItem GetNextNode(bool visible)
        {
            TreeViewItem container = null;
            if ((!visible || this.IsExpanded) && (base.Items.Count > 0))
            {
                container = (TreeViewItem)base.GetContainer(base.Items[0]);
                if ((container == null) || (container.IsEnabled && (container.Visibility == Visibility.Visible)))
                {
                    return container;
                }
                if (container.IsEnabled && !visible)
                {
                    return container;
                }
                return container.GetNextNode(visible);
            }
            IList parentCollection = base.ParentCollection;
            int num = this.Index + 1;
            if (num < parentCollection.Count)
            {
                container = (TreeViewItem)base.ParentPresenter.GetContainer(parentCollection[num]);
                if ((container == null) || (container.IsEnabled && (container.Visibility == Visibility.Visible)))
                {
                    return container;
                }
                if (container.IsEnabled && !visible)
                {
                    return container;
                }
                return container.GetNextNode(visible);
            }
            for (TreeViewItem item2 = this.ParentItem; item2 != null; item2 = item2.ParentItem)
            {
                parentCollection = item2.ParentCollection;
                num = item2.Index + 1;
                if (num < parentCollection.Count)
                {
                    container = (TreeViewItem)item2.ParentPresenter.GetContainer(parentCollection[num]);
                    if ((container == null) || (container.IsEnabled && (container.Visibility == Visibility.Visible)))
                    {
                        return container;
                    }
                    if (container.IsEnabled && !visible)
                    {
                        return container;
                    }
                    return container.GetNextNode(visible);
                }
            }
            return null;
        }

        private TreeViewItem GetPrevNode(bool visible)
        {
            TreeViewItem container = null;
            int index = this.Index;
            if (index <= 0)
            {
                container = this.ParentItem;
                if ((container == null) || (container.IsEnabled && (container.Visibility == Visibility.Visible)))
                {
                    return container;
                }
                if (container.IsEnabled && !visible)
                {
                    return container;
                }
                return container.GetPrevNode(visible);
            }
            container = (TreeViewItem)base.ParentPresenter.GetContainer(base.ParentCollection[index - 1]);
            if ((!visible || container.IsExpanded) && (container.Items.Count > 0))
            {
                for (TreeViewItem item2 = (TreeViewItem)container.GetContainer(container.Items[0]); item2 != this; item2 = item2.GetNextNode(visible))
                {
                    container = item2;
                    if (container == null)
                    {
                        break;
                    }
                }
            }
            if ((container == null) || (container.IsEnabled && (container.Visibility == Visibility.Visible)))
            {
                return container;
            }
            if (container.IsEnabled && !visible)
            {
                return container;
            }
            return container.GetPrevNode(visible);
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private void HandleIsExpandedPropertyChanged()
        {
            if (this._isLoaded)
            {
                SourcedEventArgs e = new SourcedEventArgs
                {
                    Source = this
                };
                if (this.IsExpanded)
                {
                    this.OnExpanding(e);
                }
                else
                {
                    this.OnCollapsing(e);
                }
                TreeView treeView = this.TreeView;
                this._elementExpandButton.IsChecked = new bool?(this.IsExpanded);
                if ((!this.IsExpanded && (treeView.SelectedItem != null)) && base.IsAncestorOf(treeView.SelectedItem))
                {
                    this.IsSelected = true;
                }
                if (this.IsExpanded)
                {
                    treeView.RegisterExpandedItem(this);
                    this.OnExpanded(e);
                }
                else
                {
                    treeView.UnRegisterExpandedItem(this);
                    this.OnCollapsed(e);
                }
            }
        }

        private void HandleIsSelectedPropertyChanged()
        {
            if (this._isLoaded)
            {
                this.TreeView.HandleSelectionChange(this, this.IsSelected);
            }
        }

        private int IndexFromTreeViewItem(TreeViewItem item)
        {
            if (item == null)
            {
                return -1;
            }
            int index = base.Items.IndexOf(item);
            if (index != -1)
            {
                return index;
            }
            return base.ItemContainerGenerator.IndexFromContainer(item);
        }

        private void InitializeExpandButtonPart()
        {
            this._elementExpandButton.Checked += (s, e) => this.OnExpandButtonClick();
            this._elementExpandButton.Unchecked += (s, e) => this.OnExpandButtonClick();
        }

        private void InitializeHeaderPart()
        {
            this._elementHeader.IsTabStop = false;
            if (base._elementHeaderPresenter == null)
            {
                try
                {
                    this._elementHeader.Content = base.Header;
                }
                catch (InvalidOperationException)
                {
                    FrameworkElement header = base.Header as FrameworkElement;
                    if (header != null)
                    {
                        header.RemoveFromParent();
                        this._elementHeader.Content = base.Header;
                    }
                }
            }
        }

        private void InvokeDeferredProperties()
        {
            if (this.IsExpanded)
            {
                this.HandleIsExpandedPropertyChanged();
            }
            if (this.IsSelected)
            {
                this.HandleIsSelectedPropertyChanged();
            }
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return (item is TreeViewItem);
        }

        private static void IsLastItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
        {
            (d as TreeViewItem).ChangeVisualStateItemLine(true);
        }

        private void LineAdjustment()
        {
            string errors = string.Empty;
            TreeViewLine line = new TreeViewLine();
            Path path = new Path();
            double num = 20.0;
            switch (this.Position)
            {
                case ItemPosition.Exclusive:
                    line = this.GetTemplateChild<TreeViewLine>("ExclusiveItemLine", true, ref errors);
                    if (line != null)
                    {
                        line.ApplyTemplate();
                        path = line._elementLine as Path;
                        if (path == null)
                        {
                            break;
                        }
                        path.Height = line.Height = (this._elementHeader.DesiredSize.Height > num) ? this._elementHeader.DesiredSize.Height : num;
                        path.Data = this.LineData(0.0, 0.0, path.Height / 2.0, path.Height / 2.0);
                        return;
                    }
                    return;

                case ItemPosition.Root:
                    line = this.GetTemplateChild<TreeViewLine>("RootItemLine", true, ref errors);
                    if (line != null)
                    {
                        line.ApplyTemplate();
                        path = line._elementLine as Path;
                        if (path == null)
                        {
                            break;
                        }
                        path.Height = line.Height = (this._elementHeader.DesiredSize.Height > num) ? this._elementHeader.DesiredSize.Height : num;
                        path.Data = this.LineData(path.Height, path.Height / 2.0, path.Height / 2.0, path.Height / 2.0);
                        return;
                    }
                    return;

                case ItemPosition.Last:
                    line = this.GetTemplateChild<TreeViewLine>("LastItemLine", true, ref errors);
                    if (line != null)
                    {
                        line.ApplyTemplate();
                        path = line._elementLine as Path;
                        if (path == null)
                        {
                            break;
                        }
                        path.Height = line.Height = (this._elementHeader.DesiredSize.Height > num) ? this._elementHeader.DesiredSize.Height : num;
                        path.Data = this.LineData(0.0, path.Height / 2.0, path.Height / 2.0, path.Height / 2.0);
                        return;
                    }
                    return;

                default:
                    line = this.GetTemplateChild<TreeViewLine>("NormalItemLine", true, ref errors);
                    if (line == null)
                    {
                        return;
                    }
                    line.ApplyTemplate();
                    path = line._elementLine as Path;
                    if (path != null)
                    {
                        path.Height = line.Height = (this._elementHeader.DesiredSize.Height > num) ? this._elementHeader.DesiredSize.Height : num;
                        path.Data = this.LineData(0.0, path.Height, path.Height / 2.0, path.Height / 2.0);
                    }
                    break;
            }
        }

        private PathGeometry LineData(double m1, double p1, double m2, double p2)
        {
            double x = 6.5;
            double num2 = 15.0;
            PathGeometry geometry = new PathGeometry();
            PathFigureCollection figures = new PathFigureCollection();
            PathFigure figure = new PathFigure
            {
                StartPoint = new Point(x, m1)
            };
            PathSegmentCollection segments = new PathSegmentCollection();
            PolyLineSegment segment = new PolyLineSegment
            {
                Points = new PointCollection { new Point(x, p1) }
            };
            segments.Add(segment);
            figure.Segments = segments;
            figures.Add(figure);
            PathFigure figure2 = new PathFigure
            {
                StartPoint = new Point(x, m2)
            };
            PathSegmentCollection segments2 = new PathSegmentCollection();
            PolyLineSegment segment2 = new PolyLineSegment
            {
                Points = new PointCollection { new Point(num2, p2) }
            };
            segments2.Add(segment2);
            figure2.Segments = segments2;
            figures.Add(figure2);
            geometry.Figures = figures;
            return geometry;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            if (PlatformIndependent.IsInDesignMode(this))
            {
                this.InvokeDeferredProperties();
            }
            return base.MeasureOverride(constraint);
        }

        private void OnAfterApplyTemplate()
        {
            MouseEventHandler handler = null;
            MouseEventHandler handler2 = null;
            if (this._templateLoadedProperly)
            {
                if (!PlatformIndependent.IsInDesignMode(this))
                {
                    this.InvokeDeferredProperties();
                }
                this.ResetExpandButton();
                if (this._ensureVisible)
                {
                    this.EnsureVisible();
                    this._ensureVisible = false;
                }
                Grid element = this._elementHeaderPanelContainer ?? this._elementHeaderPanel;
                this._tapHelper = new TapHelper(element, false);
                this._tapHelper.Tapped += new EventHandler<TappedEventArgs>(this.OnTapped);
                if (handler == null)
                {
                    handler = (s, e) => base.ForceMouseOver = base.IsMouseOver = true;
                }
                element.MouseEnter += handler;
                if (handler2 == null)
                {
                    handler2 = (s, e) => base.ForceMouseOver = base.IsMouseOver = false;
                }
                element.MouseLeave += handler2;
            }
            this.ChangeVisualStateShowLines(false);
            this.ChangeVisualStateItemLine(false);
            if ((this._elementExpandButton != null) && (this._elementExpandButton is TreeViewExpandButton))
            {
                (this._elementExpandButton as TreeViewExpandButton).SetBinding<TreeViewItem>(TreeViewExpandButton.ShowLinesProperty, this, x => x.ShowLines);
            }
        }

        public override void OnApplyTemplate()
        {
            this.OnBeforeApplyTemplate();
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementHeaderPanel = this.GetTemplateChild<Grid>("HeaderPanel", true, ref errors);
            this._elementHeader = this.GetTemplateChild<ContentControl>("Header", true, ref errors);
            if (this._elementHeader != null)
            {
                this.InitializeHeaderPart();
            }
            this._elementExpandButton = this.GetTemplateChild<ToggleButton>("ExpandButton", true, ref errors);
            if (this._elementExpandButton != null)
            {
                this.InitializeExpandButtonPart();
            }
            this._elementChildrenPanel = this.GetTemplateChild<ItemsPresenter>("ChildrenPanel", true, ref errors);
            this._elementHeaderPanelContainer = this.GetTemplateChild<Grid>("HeaderPanelContainer", false, ref errors);
            this._elementHeaderEditor = this.GetTemplateChild<ContentControl>("HeaderEditor", false, ref errors);
            if (!string.IsNullOrEmpty(errors))
            {
                this._templateLoadedProperly = false;
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to TreeViewItem.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this._templateLoadedProperly = true;
                this.ChangeVisualStateExpandedStates(false);
                this.ChangeVisualStateSelection(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnBeforeApplyTemplate()
        {
            if ((base._elementHeaderPresenter == null) && (this._elementHeader != null))
            {
                this._elementHeader.Content = null;
            }
        }

        protected virtual void OnClick(SourcedEventArgs e)
        {
            if (this.Click != null)
            {
                this.Click(this, e);
            }
            this.TreeView.OnItemClick(e);
        }

        protected virtual void OnCollapsed(SourcedEventArgs e)
        {
            if (this.Collapsed != null)
            {
                this.Collapsed(this, e);
            }
            this.TreeView.OnItemCollapsed(e);
        }

        protected virtual void OnCollapsing(SourcedEventArgs e)
        {
            if (this.Collapsing != null)
            {
                this.Collapsing(this, e);
            }
            this.TreeView.OnItemCollapsing(e);
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        {
            if (this._peer == null)
            {
                this._peer = AutomationPeerFactory.CreateAutomationPeer(this, typeof(TreeViewItem));
            }
            if (this._peer == null)
            {
                return base.OnCreateAutomationPeer();
            }
            return this._peer;
        }

        protected virtual void OnExpandButtonClick()
        {
            if (this._elementExpandButton.IsChecked == true)
            {
                this.Expand();
            }
            else
            {
                this.Collapse();
            }
        }

        protected virtual void OnExpanded(SourcedEventArgs e)
        {
            if (this.Expanded != null)
            {
                this.Expanded(this, e);
            }
            this.TreeView.OnItemExpanded(e);
        }

        protected virtual void OnExpanding(SourcedEventArgs e)
        {
            if (this.Expanding != null)
            {
                this.Expanding(this, e);
            }
            this.TreeView.OnItemExpanding(e);
        }

        protected override void OnHeaderChanged(object oldValue)
        {
            base.OnHeaderChanged(oldValue);
            if ((base._elementHeaderPresenter == null) && (this._elementHeader != null))
            {
                this._elementHeader.Content = base.Header;
            }
        }

        private void OnIsExpandedChanged(bool oldValue)
        {
            this.HandleIsExpandedPropertyChanged();
        }

        private static void OnIsExpandedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TreeViewItem item = d as TreeViewItem;
            bool oldValue = (bool)e.OldValue;
            item.OnIsExpandedChanged(oldValue);
            item.ChangeVisualStateExpandedStates(true);
        }

        private void OnIsSelectedChanged(bool oldValue)
        {
            this.HandleIsSelectedPropertyChanged();
        }

        private static void OnIsSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TreeViewItem item = d as TreeViewItem;
            bool oldValue = (bool)e.OldValue;
            item.OnIsSelectedChanged(oldValue);
            item.ChangeVisualStateSelection(true);
        }

        protected internal override void OnItemCleared(ItemPreparedEventArgs e)
        {
            base.OnItemCleared(e);
            this.TreeView.OnItemCleared(e);
        }

        protected internal override void OnItemPrepared(ItemPreparedEventArgs e)
        {
            base.OnItemPrepared(e);
            this.TreeView.OnItemPrepared(e);
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                for (int i = 0; i < base.Items.Count; i++)
                {
                    TreeViewItem item = this.TreeViewItemFromIndex(i);
                    if (item != null)
                    {
                        item.Position = (i == (base.Items.Count - 1)) ? ItemPosition.Last : ItemPosition.Normal;
                    }
                }
            }
            base.OnItemsChanged(e);

            for (int j = 0; j < base.Items.Count; j++)
            {
                TreeViewItem item2 = this.TreeViewItemFromIndex(j);
                if (item2 != null)
                {
                    item2.Position = (j == (base.Items.Count - 1)) ? ItemPosition.Last : ItemPosition.Normal;
                    item2.LineAdjustment();
                }
            }
            
            this.ResetExpandButton();
            if (e.NewItems != null)
            {
                foreach (object obj2 in e.NewItems)
                {
                    HierarchicalPresenter presenter = obj2 as HierarchicalPresenter;
                    if (presenter != null)
                    {
                        presenter.InitializePresenter(null, this);
                    }
                }
            }
            if ((e.Action == NotifyCollectionChangedAction.Reset) && this._isLoaded)
            {
                this.TreeView.ClearSelection();
            }
        }

        protected virtual void OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            this.TreeView.OnKeyDown(new KeyEventArgs(e));
        }

        protected internal virtual void OnTapped(object sender, TappedEventArgs e)
        {
            this.TryCaptureMouse();
            this.TreeView.HandleSelectionChange(this);
            SourcedEventArgs args = new SourcedEventArgs
            {
                Source = this
            };
            this.OnClick(args);
            if (this.TreeView.ExpandOnClick)
            {
                this.IsExpanded = !this.IsExpanded;
            }
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            TreeViewItem item2 = element as TreeViewItem;
            this.TreeView.RegisterDragSource(item2);
            FrameworkElement target = element as FrameworkElement;
            if (target != null)
            {
                if (item2 != item)
                {
                    DataTemplate itemDataTemplate = this.GetItemDataTemplate(item2, item);
                    if (itemDataTemplate is HierarchicalDataTemplate)
                    {
                        HierarchicalDataTemplate template2 = itemDataTemplate as HierarchicalDataTemplate;
                        item2.SetBinding(ItemsControl.ItemsSourceProperty, template2.ItemsSource);
                        if (template2.ItemTemplate == null)
                        {
                            item2.ItemTemplate = base.ItemTemplate;
                        }
                        else
                        {
                            item2.ItemTemplate = template2.ItemTemplate;
                        }
                    }
                }
                target.SetBinding<TreeViewItem>(Control.FontFamilyProperty, this, tvi => tvi.FontFamily);
                target.SetBinding<TreeViewItem>(Control.FontSizeProperty, this, tvi => tvi.FontSize);
                target.SetBinding<TreeViewItem>(Control.FontStretchProperty, this, tvi => tvi.FontStretch);
                target.SetBinding<TreeViewItem>(Control.FontStyleProperty, this, tvi => tvi.FontStyle);
                target.SetBinding<TreeViewItem>(Control.FontWeightProperty, this, tvi => tvi.FontWeight);
                target.SetBinding<TreeViewItem>(Control.ForegroundProperty, this, tvi => tvi.Foreground);
                target.SetBinding<TreeViewItem>(SelectedBackgroundProperty, this, tvi => tvi.SelectedBackground);
                target.SetBinding<TreeViewItem>(MouseOverBrushProperty, this, tvi => tvi.MouseOverBrush);
                target.SetBinding<TreeViewItem>(EditTemplateProperty, this, tv => tv.EditTemplate);
                TreeViewItem item3 = target as TreeViewItem;
                if (item3 != null)
                {
                    item3.SetBinding<TreeViewItem>(ShowLinesProperty, this, x => x.ShowLines);
                    item3.SetBinding<TreeViewItem>(LineStrokeProperty, this, x => x.LineStroke);
                    item3.SetBinding<TreeViewItem>(LineThicknessProperty, this, x => x.LineThickness);
                    item3.SetBinding<TreeViewItem>(LineDashArrayProperty, this, x => x.LineDashArray);
                    item3.Position = (base.Items[base.Items.Count - 1] == item) ? ItemPosition.Last : ItemPosition.Normal;
                    if ((item3.Position == ItemPosition.Last) && (base.Items.Count > 1))
                    {
                        this.TreeViewItemFromIndex(base.Items.Count - 2).Position = ItemPosition.Normal;
                    }
                }
            }
        }

        private void ResetExpandButton()
        {
            if (this._elementExpandButton != null)
            {
                bool flag = (base.Items != null) && (base.Items.Count > 0);
                this._elementExpandButton.Visibility = flag ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        private void ScrollIntoView(System.Windows.Controls.ScrollViewer sv, Rect r)
        {
            if (this.TreeView.AutoScrollMode == AutoScrollMode.Both)
            {
                if (sv.HorizontalOffset > r.Left)
                {
                    sv.ScrollToHorizontalOffset(r.Left);
                }
                else if ((sv.HorizontalOffset < (r.Right - sv.ViewportWidth)) && (sv.ViewportWidth > r.Width))
                {
                    sv.ScrollToHorizontalOffset(r.Right - sv.ViewportWidth);
                }
            }
            if ((this.TreeView.AutoScrollMode == AutoScrollMode.Both) || (this.TreeView.AutoScrollMode == AutoScrollMode.Vertical))
            {
                if (sv.VerticalOffset > r.Top)
                {
                    sv.ScrollToVerticalOffset(r.Top);
                }
                else if (sv.VerticalOffset < (r.Bottom - sv.ViewportHeight))
                {
                    sv.ScrollToVerticalOffset(r.Bottom - sv.ViewportHeight);
                }
            }
        }

        private void SetCustomDefaultValues()
        {
            base.KeyDown += new KeyEventHandler(this.OnKeyDown);
            base.SizeChanged += new SizeChangedEventHandler(this.TreeViewItem_SizeChanged);
            base.IsEnabledChanged += delegate(object s, DependencyPropertyChangedEventArgs e)
            {
                if (!base.IsEnabled)
                {
                    base.ForceMouseOver = base.IsMouseOver = false;
                }
            };
            base.IsTabStop = true;
        }

        private static void ShowLinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
        {
            (d as TreeViewItem).ChangeVisualStateShowLines(true);
        }

        internal void StartEditing()
        {
            if (this._elementHeaderEditor != null)
            {
                object header = base.Header;
                this._elementHeaderEditor.Content = header;
                this._elementHeaderEditor.Visibility = Visibility.Visible;
                this._elementHeader.Visibility = Visibility.Collapsed;
                IEditableCollectionView itemsSource = base.ParentPresenter.ItemsSource as IEditableCollectionView;
                IEditableObject obj3 = header as IEditableObject;
                if ((itemsSource != null) && (itemsSource.CurrentEditItem != header))
                {
                    itemsSource.EditItem(header);
                }
                else if (obj3 != null)
                {
                    obj3.BeginEdit();
                }
                base.LostFocus += new RoutedEventHandler(this.TreeViewItem_LostFocus);
                base.Dispatcher.BeginInvoke(new Action(this.ActivateEditor));
                this._isEditing = true;
            }
        }

        private void TreeViewItem_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.LineAdjustment();
        }

        private TreeViewItem TreeViewItemFromIndex(int index)
        {
            if ((index < base.Items.Count) && (index >= 0))
            {
                return this.TreeViewItemFromItem(base.Items[index]);
            }
            return null;
        }

        private TreeViewItem TreeViewItemFromItem(object item)
        {
            TreeViewItem item2 = item as TreeViewItem;
            if (item2 != null)
            {
                return item2;
            }
            return (TreeViewItem)base.ItemContainerGenerator.ContainerFromItem(item);
        }

        // Properties
        internal Rect Bounds
        {
            get
            {
                if (this._isLoaded)
                {
                    FrameworkElement container = this.TreeView.GetContainer(this.TreeView.Items[0]);
                    Point point = this._elementHeaderPanel.TransformToVisual(container).Transform(new Point(0.0, 0.0));
                    return new Rect(point.X, point.Y, this._elementHeaderPanel.ActualWidth, this._elementHeaderPanel.ActualHeight);
                }
                return new Rect();
            }
        }

        public DataTemplate EditTemplate
        {
            get { return (DataTemplate)GetValue(EditTemplateProperty); }
            set { SetValue(EditTemplateProperty, value); }
        }

        public TreeViewItem FirstNode
        {
            get
            {
                if (base.Items.Count <= 0)
                {
                    return null;
                }
                return (TreeViewItem)base.GetContainer(base.Items[0]);
            }
        }

        public int Index
        {
            get
            {
                return base.GetParentContainers<TreeViewItem>().IndexOf(this);
            }
        }

        public bool IsExpanded
        {
            get { return (bool)GetValue(IsExpandedProperty); }
            set { SetValue(IsExpandedProperty, value); }
        }

        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        public TreeViewItem LastNode
        {
            get
            {
                if (base.Items.Count <= 0)
                {
                    return null;
                }
                return (TreeViewItem)base.GetContainer(base.Items[base.Items.Count - 1]);
            }
        }

        public DoubleCollection LineDashArray
        {
            get { return (DoubleCollection)GetValue(LineDashArrayProperty); }
            set { SetValue(LineDashArrayProperty, value); }
        }

        public Brush LineStroke
        {
            get { return (Brush)GetValue(LineStrokeProperty); }
            set { SetValue(LineStrokeProperty, value); }
        }

        public double LineThickness
        {
            get { return (double)GetValue(LineThicknessProperty); }
            set { SetValue(LineThicknessProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public TreeViewItem NextNode
        {
            get { return this.GetNextNode(false); }
        }

        public TreeViewItem NextVisibleNode
        {
            get { return this.GetNextNode(true); }
        }

        public TreeViewItem ParentItem
        {
            get
            {
                if (base.ParentPresenter == null)
                {
                    throw new InvalidOperationException("TreeViewItem must be initialized in order to perform this action");
                }
                return (base.ParentPresenter as TreeViewItem);
            }
        }

        internal ItemPosition Position
        {
            get { return (ItemPosition)GetValue(PositionProperty); }
            set { SetValue(PositionProperty, value); }
        }

        public TreeViewItem PrevNode
        {
            get { return this.GetPrevNode(false); }
        }

        public TreeViewItem PrevVisibleNode
        {
            get { return this.GetPrevNode(true); }
        }

        public Brush SelectedBackground
        {
            get { return (Brush)GetValue(SelectedBackgroundProperty); }
            set { SetValue(SelectedBackgroundProperty, value); }
        }

        internal bool ShowLines
        {
            get { return (bool)GetValue(ShowLinesProperty); }
            set { SetValue(ShowLinesProperty, value); }
        }

        public TextAlignment TextAlignment
        {
            get { return (TextAlignment)GetValue(TextAlignmentProperty); }
            set { SetValue(TextAlignmentProperty, value); }
        }

        public TextDecorationCollection TextDecorations
        {
            get { return (TextDecorationCollection)GetValue(TextDecorationsProperty); }
            set { SetValue(TextDecorationsProperty, value); }
        }

        public TextWrapping TextWrapping
        {
            get { return (TextWrapping)GetValue(TextWrappingProperty); }
            set { SetValue(TextWrappingProperty, value); }
        }

        public TreeView TreeView
        {
            get
            {
                if (base.RootPresenter == null)
                {
                    throw new InvalidOperationException("TreeViewItem must be initialized in order to perform this action");
                }
                if (!(base.RootPresenter is TreeView))
                {
                    throw new InvalidOperationException("TreeViewItem must be descendant of a TreeView control");
                }
                return (TreeView)base.RootPresenter;
            }
        }
    }

    internal enum ItemPosition
    {
        Normal,
        Exclusive,
        Root,
        Last
    }
}
